home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1999
/
MacHack 1999.toast
/
The Hacks
/
DesktopDoubler
/
NubApp
/
Notice.c
< prev
next >
Wrap
Text File
|
1999-06-23
|
8KB
|
353 lines
#define DISABLE_LOCAL_CALLTRACE 1 // Set to 1 to disable Call Traces for this file.
#define DISABLE_LOCAL_DEBUG 0 // Set to 1 to disable all debugging for this file.
#include "DebugUtils.h"
#include <ctype.h>
#include <Icons.h>
#include <Fonts.h>
#include <Gestalt.h>
#include <Notification.h>
#include <Resources.h>
#include <stdio.h>
#include <string.h>
#include "Main.h"
#include "Notice.h"
#include "QDUtils.h"
#include "StringUtils.h"
void PreflightNotice(Boolean blockEvents)
{
char name[32];
EventRecord event;
Str255 msg;
NMRec nmpb;
OSStatus err;
// Are we the front process?
if (WeAreFrontProcess())
return;
// Post a notification, and wait until
// our process is switched to the front.
GetAppNameCString(name);
msg[0] = sprintf((char*)&msg[1],"%s requires your attention. Please bring %s to the front.",name,name);
memset(&nmpb,0,sizeof(nmpb));
nmpb.qType = nmType;
nmpb.nmMark = 1;
err = GetIconSuite(&nmpb.nmIcon,128,svAllSmallData);
if (err != noErr)
nmpb.nmIcon = NULL;
nmpb.nmSound = (Handle)-1;
nmpb.nmStr = msg;
NMInstall(&nmpb);
if (blockEvents)
{
while(!WeAreFrontProcess())
{
EventRecord event;
WaitNextEvent(0,&event,60L,NULL);
}
}
else
{
while(!WeAreFrontProcess())
SubEventLoop(everyEvent,1L);
}
NMRemove(&nmpb);
if (nmpb.nmIcon) DisposeIconSuite(nmpb.nmIcon,true);
if (nmpb.nmResp) DisposeRoutineDescriptor(nmpb.nmResp);
}
void PostNotice(AlertType type,const StringPtr error,const StringPtr detail)
{
AlertStdAlertParamRec param;
short item;
// Ensure we are front process.
PreflightNotice(false);
// Do it our way..call CompatibleStandardAlert and we'll be done.
param.movable = false;
param.helpButton = false;
param.filterProc = NULL;
param.defaultText = (StringPtr)-1L; // default = "OK"
param.cancelText = NULL; // no cancel button
param.otherText = NULL; // no other button
param.defaultButton = kAlertStdAlertOKButton;
param.cancelButton = 0;
param.position = 0; // Alert position on main screen
CompatibleStandardAlert(type,error,detail,¶m,&item);
}
Boolean PostQuestion(AlertType type,const StringPtr error,const StringPtr detail)
{
AlertStdAlertParamRec param;
short item;
// Ensure we are front process.
PreflightNotice(false);
// Do it our way..call CompatibleStandardAlert and we'll be done.
param.movable = false;
param.helpButton = false;
param.filterProc = NULL;
param.defaultText = (StringPtr)-1L; // default = "OK"
param.cancelText = (StringPtr)-1L; // default = "Cancel'
param.otherText = NULL; // no other button
param.defaultButton = kAlertStdAlertOKButton;
param.cancelButton = kAlertStdAlertCancelButton;
param.position = 0; // Alert position on main screen
CompatibleStandardAlert(type,error,detail,¶m,&item);
return (item == 1);
}
#define kCSATextBoxTop 9
#define kCSATextBoxLeft 76
#define kCSATextBoxWidth (368 - kCSATextBoxLeft - 10)
#define kCSATextBoxSeparator 5
#define kCSATextBoxCompensation 10
typedef struct CSAInfo
{
StringPtr errorText;
StringPtr detailText;
AlertType alertType;
} CSAInfo;
OSErr CompatibleStandardAlert(AlertType inAlertType,StringPtr inError,StringPtr inExplanation,
AlertStdAlertParamPtr inAlertParam,SInt16 *outItemHit)
{
DialogPtr dialog;
SInt32 result;
OSStatus err;
err = Gestalt('appr',&result);
if ((err == noErr) && (result & 1))
return StandardAlert(inAlertType,inError,inExplanation,inAlertParam,outItemHit);
dialog = GetNewDialog(1000,NULL,(WindowPtr)(-1L));
if (dialog)
{
QDContext context(dialog);
UserItemUPP userItemUPP;
SInt16 iType,errHeight,detailHeight,height;
Point loc;
Handle iHandle;
Rect iRect;
UInt32 size;
CSAInfo info;
info.errorText = inError;
info.detailText = inExplanation;
info.alertType = inAlertType;
SetWRefCon(dialog,(long)&info);
userItemUPP = NewUserItemProc(CompatibleStandardAlertUserItem);
errHeight = DrawAutoSizedText(inError,systemFont,12,0,0,kCSATextBoxWidth,false);
detailHeight = DrawAutoSizedText(inExplanation,applFont,10,0,0,kCSATextBoxWidth,false);
height = errHeight + detailHeight + ((errHeight && detailHeight) ? (kCSATextBoxSeparator - kCSATextBoxCompensation) : 0);
SizeWindow(dialog,dialog->portRect.right,dialog->portRect.bottom + height,false);
GetDialogItem(dialog,1,&iType,&iHandle,&iRect);
OffsetRect(&iRect,0,height);
SetDialogItem(dialog,1,iType,iHandle,&iRect);
MoveControl((ControlHandle)iHandle,iRect.left,iRect.top);
GetDialogItem(dialog,2,&iType,&iHandle,&iRect);
OffsetRect(&iRect,0,height);
SetDialogItem(dialog,2,iType,iHandle,&iRect);
MoveControl((ControlHandle)iHandle,iRect.left,iRect.top);
GetDialogItem(dialog,3,&iType,&iHandle,&iRect);
iRect.bottom += height + kCSATextBoxCompensation;
SetDialogItem(dialog,3,iType,(Handle)userItemUPP,&iRect);
if (inAlertParam->defaultButton)
SetDialogDefaultItem(dialog,inAlertParam->defaultButton);
if (!inAlertParam->defaultText)
{
GetDialogItem(dialog,1,&iType,&iHandle,&iRect);
HideControl((ControlHandle)iHandle);
}
if (inAlertParam->cancelButton)
SetDialogCancelItem(dialog,inAlertParam->cancelButton);
if (!inAlertParam->cancelText)
{
GetDialogItem(dialog,2,&iType,&iHandle,&iRect);
HideControl((ControlHandle)iHandle);
}
ShowWindow(dialog);
ModalDialog(NULL,outItemHit);
DisposeRoutineDescriptor(userItemUPP);
DisposeDialog(dialog);
}
return 0;
}
pascal void CompatibleStandardAlertUserItem(WindowPtr window,short item)
{
QDContext context(window);
CSAInfo *info = (CSAInfo*)GetWRefCon(window);
short offset,iconID;
switch(info->alertType)
{
case kAlertStopAlert:
iconID = 0;
break;
case kAlertNoteAlert:
iconID = 1;
break;
case kAlertCautionAlert:
iconID = 2;
break;
default:
iconID = -1;
break;
}
if (iconID != -1)
{
CIconHandle cicon;
Rect box;
box.left = 20;
box.top = 9;
box.right = box.left + 32;
box.bottom = box.top + 32;
cicon = GetCIcon(iconID);
if (cicon)
{
PlotCIcon(&box,cicon);
DisposeCIcon(cicon);
}
else
{
Handle icon;
icon = GetIcon(iconID);
if (icon)
{
PlotIcon(&box,icon);
ReleaseResource(icon);
}
}
}
offset = DrawAutoSizedText(info->errorText,systemFont,12,kCSATextBoxLeft,kCSATextBoxTop,kCSATextBoxWidth,true);
DrawAutoSizedText(info->detailText,applFont,10,kCSATextBoxLeft,offset + kCSATextBoxSeparator,kCSATextBoxWidth,true);
}
short DrawAutoSizedText(StringPtr text,short font,short size,short left,short top,short width,Boolean draw)
{
QDContext context;
FontInfo fInfo;
Str255 ctext;
UInt32 index,len,start,end;
short cur;
if (!text || !(*text))
return top;
TextFont(font);
TextSize(size);
GetFontInfo(&fInfo);
pstrcpy(ctext,text);
len = 1 + ctext[0];
start = end = 1;
for (index = 1;index < len;index++)
{
if (isspace(ctext[index]))
{
cur = TextWidth(ctext,start,index - start);
if (cur > width)
{
if (draw)
{
MoveTo(left,top + fInfo.ascent);
DrawText(ctext,start,end - start);
}
start = end + 1;
top += fInfo.ascent + fInfo.descent + fInfo.leading;
}
end = index;
}
}
if (draw)
{
MoveTo(left,top + fInfo.ascent);
DrawText(ctext,start,index - start);
}
top += fInfo.ascent + fInfo.descent;
return top;
}
Boolean WeAreFrontProcess(void)
{
ProcessSerialNumber myPSN,frontPSN;
Boolean same;
GetCurrentProcess(&myPSN);
GetFrontProcess(&frontPSN);
SameProcess(&myPSN,&frontPSN,&same);
return same;
}